// 字典
import CONST from '@/assets/scripts/const.js'
// 字段
import * as FIELDS from '@/assets/scripts/formats/fields.js'
// 工具
import * as XLSX from 'xlsx'
import { cloneDeep } from 'lodash'
import moment from 'moment'
import store from '@/assets/scripts/store'
import CONFIG from '@/config'
import storage from '@/assets/scripts/store/user'
import { ACCESS_DEFWS } from '@/store/mutation-types'

// 判断请求地址方法（drg, drg综合分析模块请求地址用drg, 其他模块用sys）
export function getApiUrl () {
  let url = window.apiUrl.sys + 'xxx'
  console.log(url, 'url...')
  if (storage.get(ACCESS_DEFWS) === 'drg' || storage.get(ACCESS_DEFWS) === 'cash') {
    url = CONFIG.HTTP_REQUEST_URL_JAVA2
  }
  return url
}

// 医审模块 获取runParams的值
export function getRunParamsValue (configKey) {
  const arr = store.state.cmsRunParams.filter(r => {
    return r.configKey === configKey
  })
  if (arr && arr.length > 0) {
    return arr[0].configValue
  }
  return ''
}

// 获取drg模块，runParams中的参数是否为true
export function getDrgRunParamValue (paramKey) {
  let result = ''
  const runParams = store.state.runParams
  if (runParams && runParams.length > 0) {
    for (let i = 0; i < runParams.length; i++) {
      if (runParams[i].configKey === paramKey) {
        result = runParams[i].configValue
        break
      }
    }
  }
  return result
}

// drg模块 判断runParams中的参数是否为true
export function judgeRunParam (paramKey) {
  let result = false
  const runParams = store.state.runParams
  if (runParams && runParams.length > 0) {
    for (let i = 0; i < runParams.length; i++) {
      if (runParams[i].configKey === paramKey) {
        result = runParams[i].configValue === 'true'
        break
      }
    }
  }
  return result
}

export function drawImage (src, title) {
  var img = new Image()
  img.src = src
  img.setAttribute('crossOrigin', 'Anonymous')
  img.onload = () => {
    var canvas = document.createElement('canvas')
    canvas.width = img.width
    canvas.height = img.height
    var ctx = canvas.getContext('2d')
    ctx.drawImage(img, 0, 0)
    var dataURL = canvas.toDataURL('image/png')
    var a = document.createElement('a')
    // 创建一个单击事件
    var event = new MouseEvent('click')
    // 将a的download属性设置为我们想要下载的图片名称，若name不存在则使用‘下载图片名称’作为默认名称
    a.download = title + '.png'
    // 将生成的URL设置为a.href属性
    a.href = dataURL
    // 触发a的单击事件
    a.dispatchEvent(event)
  }
}

// Markdown转表格
export function tableMarkdown (dataStr) {
  const dataList = dataStr.split('||')
  const dataTable = []
  for (let i = 0; i < dataList.length; i++) {
    const dataItem = dataList[i]
    const dataVals = dataItem.split('|')
    const row = {}
    dataVals.map(val => {
      if (val) {
        row['a' + Object.keys(row).length] = val
      }
    })
    dataTable.push(row)
  }
  return dataTable
}

export function handleFormatLat12 (ops = {}, data = [], keyCode = 'billDate') {
  ops.end_time = ops.end_time || moment(new Date()).format('YYYY-MM')
  const JunList = []
  for (let i = 0; i < 12; i++) {
    const d = moment(new Date(ops.end_time.substring(0, 4) + '-01')).add(i, 'month').startOf('month').format('YYYY-MM')
    const index = data.findIndex(item => { return moment(new Date(item[keyCode])).format('YYYY-MM') === d || moment(new Date(item.time)).format('YYYY-MM') === d })
    if (index > -1) {
      JunList.push(data[index])
    } else {
      const r = {}
      r[keyCode] = d
      JunList.push(r)
    }
  }
  return JunList
}

// 格式化时间筛选  paramType用来区分俩种不同的格式
export function formatDateSelect (data = {}, paramType = 'before') {
  if (!data.value) {
    return {
      start_time: '',
      end_time: ''
    }
  }
  let opts = {}
  const type = data.type
  // 之前报表的入参格式
  if (paramType === 'before') {
    // type year quarter value
    if (type === 'quarter') {
      const y = moment(data.value).format('YYYY')
      const quarter = {
        1: [1, 3],
        2: [4, 6],
        3: [7, 9],
        4: [10, 12]
      }
      const mSection = quarter[data.quarter]
      opts = {
        start_time: moment(new Date(y + '-' + mSection[0])).startOf('month').format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(new Date(y + '-' + mSection[1])).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
      }
      // 年份
    } else if (type === 'year') {
      const y = moment(data.value).format('YYYY')
      opts = {
        start_time: y + '-01-01 00:00:00',
        end_time: y + '-12-31 23:59:59'
      }
    } else if (type === 'month') {
      const m = moment(data.value).format('YYYY-MM-DD')
      opts = {
        start_time: moment(m).startOf('month').format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(m).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
      }
    } else if (type === 'daterange') {
      opts = {
        start_time: moment(data.value[0]).format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(data.value[1]).format('YYYY-MM-DD') + ' 23:59:59'
      }
    } else if (type === 'monthrange') {
      opts = {
        start_time: moment(data.value[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(data.value[1]).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
      }
    } else if (type === 'datetimerange') {
      opts = {
        start_time: moment(data.value[0]).format('YYYY-MM-DD HH:mm:ss'),
        end_time: moment(data.value[1]).format('YYYY-MM-DD HH:mm:ss')
      }
    }
    // 嘉禾之后写的报表入参格式
  } else if (paramType === 'after') {
    // 季度
    if (type === 'quarter') {
      const y = moment(data.value).format('YYYY')
      const quarter = {
        1: [1, 4],
        2: [4, 7],
        3: [7, 10],
        4: [10, 1]
      }
      const mSection = quarter[data.quarter]
      // 季度为第四季度时，年份加一
      let endTime
      if (data.quarter === '4') {
        endTime = moment(y).add(1, 'year').format('YYYY') + '-01-01 00:00:00'
      } else {
        endTime = moment(new Date(y + '-' + mSection[1])).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
      }
      opts = {
        start_time: moment(new Date(y + '-' + mSection[0])).startOf('month').format('YYYY-MM-DD') + ' 00:00:00',
        end_time: endTime
      }
      // 年份
    } else if (type === 'year') {
      const y = moment(data.value).format('YYYY')
      opts = {
        start_time: y + '-01-01 00:00:00',
        end_time: moment(y).add(1, 'year').format('YYYY') + '-01-01 00:00:00'
      }
    } else if (type === 'month') {
      const m = moment(data.value).format('YYYY-MM-DD')
      opts = {
        start_time: moment(m).startOf('month').format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(m).add(1, 'month').startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
      }
    } else if (type === 'daterange') {
      const end = moment(data.value[1]).format('YYYY-MM-DD')
      opts = {
        start_time: moment(data.value[0]).format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(end).add(1, 'day').format('YYYY-MM-DD') + ' 00:00:00'
      }
    } else if (type === 'monthrange') {
      opts = {
        start_time: moment(data.value[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00',
        end_time: moment(data.value[1]).add(1, 'month').startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
      }
    } else if (type === 'datetimerange') {
      opts = {
        start_time: moment(data.value[0]).format('YYYY-MM-DD HH:mm:ss'),
        end_time: moment(data.value[1]).format('YYYY-MM-DD HH:mm:ss')
      }
    }
  }
  return opts
}

// 解析excel
export function xlsxExcelBlob (blob, cb, sheetIndex) {
  const reader = new FileReader()
  reader.onload = e => {
    // 预处理
    var binary = ''
    var buf = new Uint8Array(e.target.result)
    var length = buf.byteLength
    for (var i = 0; i < length; i++) {
      binary += String.fromCharCode(buf[i])
    } // 读取excel
    const wb = XLSX.read(binary, { type: 'binary', cellFormula: true, cellStyles: true, bookDeps: true })
    // 抓取第一个sheet
    const wsname = wb.SheetNames[sheetIndex || 0]
    const ws = wb.Sheets[wsname]
    // console.log(wb)
    const fileContent = XLSX.utils.sheet_to_html(ws)
    if (cb) cb(fileContent)
  }
  reader.readAsArrayBuffer(blob)
}

// 计算住院时间
export function calcInDepDays (start, end) {
  start = start ? new Date(moment(new Date(start)).format('YYYY-MM-DD')).getTime() : 0
  end = start ? new Date(moment(new Date(end)).format('YYYY-MM-DD')).getTime() : 0
  const inHosDay = Math.ceil((end - start) / (24 * 60 * 60 * 1000))
  return inHosDay > 1 ? inHosDay : 1
}

export function formatToLine (value) {
  return value.replace(/([A-Z])/g, '_$1').toLowerCase()
}

// 下划线转驼峰
export function toHump (string) {
  return string.replace(/_(\w)/g, function (all, letter) {
    return letter.toUpperCase()
  })
}

// 下划线转驼峰(批量)
export function toHumpBatch (data = []) {
  return data.map(item => {
    return toHumpObj(item)
  })
}

// 下划线转驼峰(对象)
export function toHumpObj (item = {}) {
  for (const key in item) {
    const value = item[key]
    delete item[key]
    item[toHump(key)] = value
  }
  return item
}

// 搜索时 合并对象 保留oldObj的值 并 用newObj替换nowObj
export function objectAssign (oldObj, nowObj, newObj) {
  const obj = Object.assign({}, oldObj, nowObj, newObj)
  for (const key in obj) {
    // 删除为空的 非默认值
    if ((oldObj && key in oldObj) || (newObj && key in newObj)) {

    } else {
      delete obj[key]
    }
    // if ((oldObj && !oldObj[key]) && (newObj && (!newObj[key] || JSON.stringify(newObj[key]) === '{}'))) {
    //   delete obj[key]
    // }
  }
  return obj
}

// 获取 {code value} 的显示值
export function stringCodeValue (field) {
  field = formatCodeValue(field)
  return field.value || field.code
}

// 格式化 返回 {code value}
export function formatCodeValue (field) {
  const defStr = ''
  if (typeof field === 'object' && field) {
    return {
      code: field.code || defStr,
      value: field.value || field.code || defStr
    }
  } else {
    return {
      code: field || defStr,
      value: field || defStr
    }
  }
}

// 根据返回数据的code值 获取本地字典 type-const.js中类型
export function getConstByCode (type, keyCode, dataOld) {
  let data = CONST[type] || {}
  if (typeof data === 'function') {
    data = data()
  }
  if (dataOld) {
    data = dataOld || {}
  }
  let rData = {
    keyCode: keyCode,
    lable: keyCode,
    const: keyCode
  }
  for (const key in data) {
    const item = data[key]
    if (item.keyCode === keyCode) {
      rData = item
      rData.const = key
    }
  }
  return rData
}

// 返回不同类型的字段，如 type为select-remote的有哪些字段[字段1, 字段2]
export function formatConstType (typeList) {
  const rList = []
  const const02 = CONST.constFun()
  for (const key in const02.mainDataField) {
    const item = const02.mainDataField[key]
    if (typeList.indexOf(item.type) > -1) {
      rList.push(item.keyCode)
    }
  }
  return rList
}

// 格式化form-edit  展示之前 对于数组类型
export function formatFormShowArray (keyCode, item, length) {
  const const02 = CONST.constFun()
  const tableData = JSON.parse(JSON.stringify(item || []))
  length = length || tableData.length
  for (let i = 0; i < length; i++) {
    const tItem = tableData[i] || {}
    const array = (const02.mainDataField[keyCode] && const02.mainDataField[keyCode].array) || []
    for (let j = 0; j < array.length; j++) {
      tItem[array[j].keyCode] = formatFormShow(array[j].keyCode, tItem[array[j].keyCode] || '')
    }
    tableData[i] = tItem
  }
  return tableData
}

// 格式化form-edit  展示之前 对于单个字段
export function formatFormShow (keyCode, item = '') {
  const const02 = CONST.constFun()
  // null 转成空
  if (item === null || item === 'None') { item = '' }
  // 转成字符串
  if (item === 0) { item = item.toString() }
  // 默认值
  const defStr = ''
  // 若是select形式的字段，需要返回对象
  const selectList = formatConstType(['select-remote'])
  // 若是select形式的字段，需要返回对象
  const cascaderAddrList = formatConstType(['cascader-addr'])
  // 若是时间字段 后台返回时间戳 需要格式化
  const timeList = formatConstType(['datetime', 'date'])
  if (selectList.indexOf(keyCode) > -1 || cascaderAddrList.indexOf(keyCode) > -1) {
    // 下拉框格式化
    if (typeof item === 'string' || typeof item === 'number') {
      item = { code: item, value: item }
      // 如果是noapi的下拉框，例如is_icu
      if (const02.mainDataField[keyCode] && const02.mainDataField[keyCode].dict && const02.mainDataField[keyCode].dict.noapi) {
        const tips = const02.mainDataField[keyCode].dict.tips || []
        const index = tips.findIndex(titem => {
          return titem.value === item.code || titem.label === item.value
        })
        if (index > -1) {
          item = { code: tips[index].value, value: tips[index].label }
        }
      }
    }
    item = { code: (item && item.code) || defStr, value: (item && item.value) || (item && item.code) || defStr }
  } else if (timeList.indexOf(keyCode) > -1) {
    // 判断是否是时间戳
    const fieldData = const02.mainDataField[keyCode] || {}
    if (item) {
      item = moment(item).format(fieldData.type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')
    }
    if (item === 'Invalid date') { item = defStr }
  } else {
    item = item || defStr
    const dataField = const02.mainDataField[keyCode]
    if (dataField && dataField.typeShow === FIELDS.TYPE_SHOW_VALUE && typeof item !== 'string') {
      // console.log(item, dataField.typeShow, keyCode)
      item = item.toString()
    }
  }
  return item
}

// 格式化form-edit  保存之前
export function formatFormEdit (keyCode, item) {
  const const02 = CONST.constFun()
  let rData = JSON.parse(JSON.stringify(item))
  const fieldData = (const02.mainDataField && const02.mainDataField[keyCode]) || {}
  const typeSave = fieldData.typeSave
  // 格式化 code、value
  if (typeSave === FIELDS.TYPE_SHOW_VALUE) {
    if (typeof item === 'object' && !Array.isArray(item)) {
      rData = ('value' in item) ? item.value : item
    } else {
      rData = item
      // 判断是否是int类型 要做转换
      if (fieldData.original.type === 'int' || fieldData.original.type === 'money') {
        rData = Number(item)
      }
    }
  } else if (typeSave === FIELDS.TYPE_SHOW_CODE) {
    if (typeof item === 'object' && !Array.isArray(item)) {
      rData = ('code' in item) ? item.code : item
    } else {
      rData = item
    }
  } else if (typeSave === FIELDS.TYPE_SHOW_CODEVALUE) {
    rData = {
      code: item.code,
      value: item.value
    }
  }
  return rData
}

// 根据搜索类型 格式化搜索数据 oldQuery { 字段名：字段值 }
// searchList 用来判断不不在mainDataField的字段类型  isVague是否模糊匹配针对input true不模糊 默认false模糊
export function formatSearchData (oldQuery = {}, searchList = [], isVague) {
  const const02 = CONST.constFun()
  if (Object.prototype.toString.call(oldQuery) === '[object Object]') {
    const newQuery = JSON.parse(JSON.stringify(oldQuery))
    const retQuery = {}
    // 初始化
    const searchObject = {}
    if (searchList && searchList.length > 0) {
      searchList.map(item => {
        searchObject[item.keyCode] = item
      })
    }
    // 格式化
    for (let keyCode in newQuery) {
      let item = newQuery[keyCode]
      const fieldData = searchObject[keyCode] || (const02.mainDataField && const02.mainDataField[keyCode]) || {}
      const typeSave = fieldData.typeSave
      const type = fieldData.type
      const typeDb = fieldData.typeDb
      item = formatFormEdit(keyCode, item)
      // 步骤二 转换成 模糊搜索 格式化时间
      if (['datetime', 'date', 'daterange'].indexOf(type) > -1) {
        if (Array.isArray(item)) {
          // 时间范围要格式化成 时间戳
          item = {
            $gte: new Date(moment(item[0]).format('YYYY-MM-DD') + ' 00:00:00').getTime(),
            $lte: new Date(moment(item[1]).format('YYYY-MM-DD') + ' 23:59:59').getTime()
          }
        } else {
          let time = moment(item).format(type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')
          if (time === 'Invalid date') {
            time = ''
          } else {
            time = new Date(time).getTime()
          }
          item = time
        }
      } else if (type === 'input') {
        if (typeDb === 'int') {
          item = item.toString().trim()
          item = Number(item)
        } else {
          // 如果是string类型 去除空格 并且是模糊查询
          if (isVague) {
            item = item.toString().trim()
          } else {
            item = {
              $regex: item.toString().trim(),
              $options: 'i'
            }
          }
        }
      } else if (type === 'select-remote' && typeSave === FIELDS.TYPE_SHOW_CODEVALUE) {
        // 如果是select类型 并且保存类型为codeValue 需要转换成a.code 查询
        keyCode = keyCode + '.code'
        item = item.code
        // console.log('..save')
      }
      // 如果是诊断或者手术字段 需要拼装成数组
      if (fieldData.isSearchParent) {
        const p = {}
        p[keyCode] = item
        keyCode = fieldData.isSearchParent
        item = {
          '$elemMatch': Object.assign({}, (retQuery[keyCode] && retQuery[keyCode].$elemMatch) || {}, (newQuery[keyCode] && newQuery[keyCode].$elemMatch) || {}, p)
        }
        // console.log(item)
        // 'outDiagnosis': {
        //   '$elemMatch': {
        //     'outHosDiagnosisCode': 'A00.100x001'
        //   }
        // }
      }
      if (typeDb === 'array') {
        item = Object.assign({}, item, retQuery[keyCode])
      }
      retQuery[keyCode] = item
    }
    return retQuery
  }
  return oldQuery
}

// 计算表格高度
export function handleTableHeight (id) {
  let doms = document.getElementById(id)
  if (doms) {
    // console.log(doms.offsetHeight, 'doms...')
    // console.log(doms.clientHeight, 'doms...')
    const offsetHeight = doms.offsetHeight
    const paddingTop = parseInt(getComputedStyle(doms, false)['paddingTop'])
    const paddingBottom = parseInt(getComputedStyle(doms, false)['paddingBottom'])
    doms = null
    // console.log(offsetHeight, paddingTop, paddingBottom)
    return offsetHeight - paddingTop - paddingBottom
  }
  return 0
}

// 打印标签
export function handlePrint (id, classOld, classNew) {
  // 打印预览
  const myWindow = window.open('', '打印预览')
  // 打印区域
  let $dom = window.document.getElementById(id)
  // 为区域内的输入框赋值
  let $inputs = $dom.querySelectorAll('.el-input__inner')
  for (let i = 0; i < $inputs.length; i++) {
    const $input = $inputs[i]
    $input.setAttribute('value', $input.value)
  }
  // 获取id为app内的html
  let bodyHtml = $dom.innerHTML
  // 获取head标签内的html
  const headHtml = window.document.head.innerHTML
  // 头中的screen换成打印样式print
  bodyHtml = bodyHtml.replace(classOld, classNew)
  setTimeout(function () {
    // 重新写入文档流
    myWindow.document.write('<html>')
    myWindow.document.write(headHtml)
    myWindow.document.write('<body style="overflow-y: auto;">')
    myWindow.document.write(bodyHtml)
    myWindow.document.write('<script>setTimeout(function() { window.print(); window.close(); }, 20)</')
    myWindow.document.write('script>')
    myWindow.document.write('</body></html>')
  }, 20)
  $dom = null
  $inputs = null
}

// 扫码枪
export function handleScanGun (cb) {
  let code = ''
  let lastTime, nextTime
  let lastCode, nextCode
  window.document.onkeypress = function (e) {
    if (window.event) { // IE
      nextCode = e.keyCode
    } else if (e.which) { // Netscape/Firefox/Opera
      nextCode = e.which
    }
    // console.time()
    // console.log('nextCode', nextCode)
    if (nextCode === 13) {
      if (code.length < 3) return // 手动输入事件的code的长度为1
      // console.log('扫码结束', code)
      // console.timeEnd()
      cb && cb(code)// 获取到扫码枪输入的内容，做别的操作
      code = ''
      lastCode = ''
      lastTime = ''
      return
    }
    nextTime = new Date().getTime()
    if (!lastTime && !lastCode) {
      // console.log('扫码开始。。。')
      code += e.key
    }
    if (lastCode && lastTime && nextTime - lastTime > 30) {
      // 当扫码前有keypress事件时,防止首字缺失
      // console.log('防止首字缺失。。。')
      code = e.key
      // 扫码枪输入的时间间隔一般在8毫秒，偶尔会有16毫秒，而键盘输入一般都在80毫秒以上，因此我设定当输入间隔小于等于30毫秒时，判断为扫码枪输入
    } else if (lastCode && lastTime) {
      // console.log('扫码中。。。')
      code += e.key
    }
    lastCode = nextCode
    lastTime = nextTime
  }
}

function cleanVnode (vnode) {
  if (vnode) {
    vnode.elm = null
    vnode._renderChildren = null
    vnode.children = null
    vnode.componentOptions = null
  }
}

// 设置分页信息
export function fPageNum (data = {}) {
  data = JSON.parse(JSON.stringify(data))
  // data.pageNum = data.pageNum || data.pageNumber || 1
  let pageSize
  if (data.pageSize === 0) {
    pageSize = 0
  } else {
    pageSize = data.pageSize || CONST.pageSize
  }
  const pageNum = data.pageNum || 1
  return {
    pageSize,
    pageNum,
    skip: (pageNum - 1) * pageSize,
    limit: pageSize
  }
}

// 隐藏重要信息
export function hiddenSensitiveData (str, frontLen = 5, endLen = 5) {
  if (str) {
    var len = str.length - frontLen - endLen
    if (len <= 0) len = str.length
    var xing = ''
    for (var i = 0; i < len; i++) {
      xing += '*'
    }
    if (str.length === 2 && frontLen === 1) {
      return str.substring(0, frontLen) + '*'
    }
    if (str.length - frontLen - endLen > 0) {
      return str.substring(0, frontLen) + xing + str.substring(str.length - endLen)
    } else {
      return xing
    }
  }
  return '*'
}

// 清除缓存
export function handleClearDetached (that) {
  if (!that) {
    return false
  }
  // console.log(that)
  that.$children = []
  that.$parent = null
  that._watchers = []
  that.$refs = {}
  that.$root = null
  that.$slots = []
  that.$store = null
  cleanVnode(that._vnode)
  cleanVnode(that.$vnode)
  that._vnode = null
  that.$vnode = null
  if (that.$el) { delete that.$el.__ro__ }
  that.$el = null
  that._watcher = null
  that._computedWatchers = {}
  // ab-aui的内存溢出问题
  that.popperElm = null
  if (that.$options) {
    that.$options.parent = null
    that._parentVnode = null
    that.$options = null
  }
  // 解除绑定
  that.$off()
  // console.log(that)
}

// 计算字符串中中文字符个数
export function computeCnStr (str = '') {
  if (str === null) { str = '' }
  let cnNum = 0
  for (let i = 0; i < str.length; i++) {
    // escape对字符串进行编码，字符值大于 255 的以 %u**** 格式存储，而字符值大于 255 的恰好是非英文字符（一般是中文字符）
    if (escape(str[i]).indexOf('%u') === 0) {
      cnNum += 1
    }
  }
  return [cnNum, str.length - cnNum]
}

// 纯前端导出表格
// 1：拿到表格数据和表头字段处理成二维数组的格式
// 2：找出每列最长的字符串，大概算出最长字符串的长度
// 3: 设置每列单元格宽度样式，然后导出
export function handleTableExport (tableField, tableData, tableName, tableFieldCn) { // 入参格式：(表头字段，表格数据，导出表格名称, 手动传入字段名称)
  // resultArr用来存放allResult转换为二维数组的数据
  const const02 = CONST.constFun()
  const resultArr = []
  for (let i = 0; i < tableData.length; i++) {
    const arr = [] // 用来存放单条表格数据
    tableField.map(fieldName => {
      if (tableData[i][fieldName] && tableData[i][fieldName].value) {
        arr.push(tableData[i][fieldName].value)
      } else if (tableData[i][fieldName] === null || tableData[i][fieldName] === undefined) {
        arr.push('-')
      } else {
        arr.push(tableData[i][fieldName])
      }
    })
    resultArr.push(arr)
  }
  // 获取表头字段信息
  let labelList = []
  if (tableFieldCn) { // 如果传参有自定义的中文字段
    labelList = tableFieldCn
  } else {
    tableField.map(fieldName => {
      const result = const02.mainDataField[fieldName].label
      labelList.push(result)
    })
  }
  // 将表头字段放入到第一位
  resultArr.unshift(labelList)
  // console.log(resultArr, 'resultArr....')
  // 定义一个数组用来保存最大长度列的字符串信息
  const maxLengthArr = []
  for (let i = 0; i < resultArr.length; i++) {
    for (let j = 0; j < resultArr[i].length; j++) {
      const length = resultArr[i][j].length
      const cnEnNumArr = computeCnStr(resultArr[i][j])
      const strLength = cnEnNumArr[0] * 13.4 + cnEnNumArr[1] * 6.4
      // 第一次还未赋值时，取第一个值
      if (maxLengthArr[j] === undefined) {
        maxLengthArr[j] = {
          length: length,
          cnNum: cnEnNumArr[0],
          enNum: cnEnNumArr[1],
          totalLength: cnEnNumArr[0] * 13.4 + cnEnNumArr[1] * 6.4
        }
      }
      // 找出resultArr二维数组中第j列字符串长度最大的值
      if (strLength > maxLengthArr[j].totalLength) {
        maxLengthArr[j].length = length
        maxLengthArr[j].cnNum = cnEnNumArr[0]
        maxLengthArr[j].enNum = cnEnNumArr[1]
        maxLengthArr[j].totalLength = cnEnNumArr[0] * 13.4 + cnEnNumArr[1] * 6.4
      }
    }
  }
  // 设置单元格宽度样式数组
  const setCellWidthArr = []
  maxLengthArr.map(r => {
    setCellWidthArr.push({ wpx: r.totalLength })
  })
  const worksheet = XLSX.utils.aoa_to_sheet(resultArr)
  const workbook = XLSX.utils.book_new()
  XLSX.utils.book_append_sheet(workbook, worksheet, 'sheet')
  // 中文字符：13.4，  英文，数字，标点：6.4
  worksheet['!cols'] = setCellWidthArr
  XLSX.writeFile(workbook, tableName + '.xls')
}

// 纯前端导出表格
// 1：拿到表格数据和表头字段处理成二维数组的格式
// 2：找出每列最长的字符串，大概算出最长字符串的长度
// 3: 设置每列单元格宽度样式，然后导出
export function handleTableExportBase (tableField, tableData, tableName, extraOptions = { headCellMerge: [], merges: [], cols: [] }) { // 入参格式：(表头字段，表格数据，导出表格名称)
  // resultArr用来存放allResult转换为二维数组的数据
  const resultArr = []
  for (let i = 0; i < tableData.length; i++) {
    const arr = []
    if (!Array.isArray(tableField)) {
      for (const fieldName in tableField) {
        if (tableData[i][fieldName] && tableData[i][fieldName].value) {
          arr.push(tableData[i][fieldName].value)
        } else if (tableData[i][fieldName] === null || tableData[i][fieldName] === undefined) {
          arr.push('-')
        } else {
          arr.push(tableData[i][fieldName])
        }
      }
    } else {
      tableField.map(item => {
        const fieldName = item.keyCode
        if (tableData[i][fieldName] && tableData[i][fieldName].value) {
          arr.push(tableData[i][fieldName].value)
        } else if (tableData[i][fieldName] === null || tableData[i][fieldName] === undefined) {
          arr.push('-')
        } else {
          arr.push(tableData[i][fieldName])
        }
      })
    }
    resultArr.push(arr)
  }
  const tbodyArr = cloneDeep(resultArr)
  // 获取表头字段信息
  const labelList = []
  if (!Array.isArray(tableField)) {
    for (const key in tableField) {
      labelList.push(tableField[key])
    }
  } else {
    tableField.map(item => {
      labelList.push(item.label)
    })
  }

  // 将表头字段放入到第一位
  resultArr.unshift(labelList)
  // 表头有单元格合并
  const resHasMerge = extraOptions.headCellMerge.length > 0 ? [...extraOptions.headCellMerge, ...tbodyArr] : []
  // console.log(resultArr, 'resultArr....')
  // 定义一个数组用来保存最大长度列的字符串信息
  const maxLengthArr = []
  for (let i = 0; i < resultArr.length; i++) {
    for (let j = 0; j < resultArr[i].length; j++) {
      const length = resultArr[i][j].length
      const cnEnNumArr = computeCnStr(resultArr[i][j])
      const strLength = cnEnNumArr[0] * 13.4 + cnEnNumArr[1] * 6.4
      // 第一次还未赋值时，取第一个值
      if (maxLengthArr[j] === undefined) {
        maxLengthArr[j] = {
          length: length,
          cnNum: cnEnNumArr[0],
          enNum: cnEnNumArr[1],
          totalLength: cnEnNumArr[0] * 13.4 + cnEnNumArr[1] * 6.4
        }
      }
      // 找出resultArr二维数组中第j列字符串长度最大的值
      if (strLength > maxLengthArr[j].totalLength) {
        maxLengthArr[j].length = length
        maxLengthArr[j].cnNum = cnEnNumArr[0]
        maxLengthArr[j].enNum = cnEnNumArr[1]
        maxLengthArr[j].totalLength = cnEnNumArr[0] * 13.4 + cnEnNumArr[1] * 6.4
      }
    }
  }
  // 设置单元格宽度样式数组
  const setCellWidthArr = []
  maxLengthArr.map(r => {
    setCellWidthArr.push({ wpx: r.totalLength })
  })
  const worksheet = XLSX.utils.aoa_to_sheet(extraOptions.headCellMerge.length > 0 ? resHasMerge : resultArr)
  const workbook = XLSX.utils.book_new()
  XLSX.utils.book_append_sheet(workbook, worksheet, 'sheet')
  // 中文字符：13.4，  英文，数字，标点：6.4
  worksheet['!cols'] = (extraOptions.cols && extraOptions.cols.length > 0) ? extraOptions.cols : setCellWidthArr
  worksheet['!merges'] = extraOptions.merges.length > 0 ? extraOptions.merges : []
  XLSX.writeFile(workbook, tableName + '.xls')
}
// 数字向上取整，如3230->3300
export function ceilNumber (number) {
  let bite = 0
  if (number < 10) {
    return 10
  }
  while (number >= 10) {
    number /= 10
    bite += 1
  }
  return Math.ceil(number) * Math.pow(10, bite)
}
/**
 * @description: 时间格式化
 * @param {*} dateSelect
 * @param {*} formatType
 * @return {*} object
 */
export function formatTimeRange (dateSelect = { type: 'year', value: new Date() }, formatType = 'YYYY-MM-DD') {
  let [beginDate, endDate] = ['', '']
  switch (dateSelect.type) {
    case 'quarter': {
      beginDate = moment().quarter(Number(dateSelect.quarter)).startOf(dateSelect.type).format(formatType)
      endDate = moment().quarter(Number(dateSelect.quarter)).endOf(dateSelect.type).format(formatType)
      break
    }
    case 'monthrange': {
      beginDate = moment(dateSelect.value[0]).startOf('month').format(formatType)
      endDate = moment(dateSelect.value[1]).endOf('month').format(formatType)
      break
    }
    case 'daterange': {
      beginDate = moment(dateSelect.value[0]).format('YYYY-MM-DD') + ' 00:00:00'
      endDate = moment(dateSelect.value[1]).format('YYYY-MM-DD') + ' 23:59:59'
      break
    }
    case 'yearrange': {
      beginDate = moment(dateSelect.value[0]).format(formatType)
      endDate = moment(dateSelect.value[1]).format(formatType)
      break
    }
    default: {
      beginDate = moment(dateSelect.value).startOf(dateSelect.type).format(formatType)
      endDate = moment(dateSelect.value).endOf(dateSelect.type).format(formatType)
    }
  }
  return {
    beginDate,
    endDate
  }
}
/**
 * @description: 预览文档
 * @param {*} url
 * @return {*}
 */
export const viewFile = function (url) {
  const onlineViewType = ['doc', 'docx', 'xls', 'xlsx', 'xlsm', 'ppt', 'pptx']
  const fileTypeName = url.substring(url.lastIndexOf('.') + 1, url.length).split('?')[0]
  const isWord = onlineViewType.find((type) => type === fileTypeName)
  if (isWord) {
    url = 'http://view.officeapps.live.com/op/view.aspx?src=' + url
  }
  window.open(url, '_blank')
}

// 数字三位间隔
export const formatThousandth = (key) => {
  if (key || key === 0) {
    key += ''
    const x = key.split('.')
    let x1 = x[0] // x1是小数点之前的
    let x2 = x.length > 1 ? '.' + x[1] : '' // x2注释的是小数点之后的间隔
    const reg = /(\d+)(\d{3})/
    while (reg.test(x1)) {
      x1 = x1.replace(reg, '$1' + ',' + '$2')
      x2 = x2.replace(reg, '$1' + ',' + '$2')
    }
    return x1 + x2
  }
  return ''
}

// 金额三位间隔,保留俩位小数
export const formatMoney = (m) => {
  if (m) {
    return formatThousandth(Number(m).toFixed(2))
  }
  return m
}

// 金额百万
export const formatMoneyMillion = (m) => {
  if (m) {
    if (Number(m) > 99.99 || Number(m) < -99.99) {
      return {
        value: formatThousandth(Number(m / 10000).toFixed(2)),
        unit: '万元'
      }
    }
    return {
      value: formatThousandth(Number(m).toFixed(2)),
      unit: '元'
    }
  }
  return {
    value: m,
    unit: '元'
  }
}

export const formatNum = (m) => {
  if (m) {
    return Number(m).toFixed(2)
  }
  return m
}

// 生成formdata格式的数据
export const toFormData = function (data) {
  if (data === null) return null
  return Object.keys(data).reduce((formData, item) => {
    if (item === 'files') { // 特殊判断如果内容为files数组，就让里面值不用走JSON.stringify
      data[item] &&
        data[item].forEach((curr) => {
          formData.append('upload_file[]', curr.originFileObj)
        })
    } else {
      formData.append(item, data[item])
    }
    return formData
  }, new FormData())
}
